using System;
using System.Text;
using System.Diagnostics;
using System.Collections.Generic;

namespace My.IdlConverter.Core
{
    using Types;

    public class Method
    {
        private IType _returnType;
        private string _name;
        private string _suffix;
        private Interface _parent;
        private IList<Parameter> _params = new List<Parameter>();
        protected bool _getter = false;
        protected bool _setter = false;

        public Method(IType retType, string name)
            :this(retType,name,"")
        {
        }
        public Method(IType retType, string name, string suffix)
        {
            _returnType = retType;
            _name = name;
            _suffix = suffix;
        }

        public IType ReturnType
        {
            get{return _returnType;}
            set { _returnType = value; }
        }

        public bool HasReturn()
        {
            return (ReturnType.TypeString.IndexOf("void") == -1);
        }

        public Interface Parent
        {
            get
            {
                return _parent;
            }
            set
            {
                _parent = value;
            }
        }

        public string Name
        {
            get
            {
                return _name;
            }
            set
            {
                _name = value;
            }
        }

        public bool Const
        {
            get
            {
                if (_suffix.Length == 0)
                    return false;
                return (_suffix.IndexOf("const") != -1);
            }
        }

        public IList<Parameter> Parameters
        {
            get
            {
                return _params;
            }
        }

        public virtual bool Getter
        {
            get
            {
                _getter = Name.StartsWith("Get",
                                         StringComparison.OrdinalIgnoreCase)
                                         && !Name.Equals("Get")
                                         && (Parameters.Count == 0);
                return _getter;
            }
            set { _getter = value; }
        }

        public virtual bool Setter
        {
            get
            {
                bool _setter = Name.StartsWith("Set",
                                         StringComparison.OrdinalIgnoreCase)
                                         && !Name.Equals("Set")
                                         && (Parameters.Count == 1);

                if (ReturnType != null)
                {
                    Debug.Assert(ReturnType.PureTypeString.Length > 0);
                    _setter = (_setter && (ReturnType.PureTypeString.Equals("void")));
                }
                return _setter;
            }
            set { _setter = value; }
        }

        public string PureName
        {
            get
            {
                if (Getter || Setter)
                {
                    string tmpMethodName = Name;
                    tmpMethodName = tmpMethodName.Remove(0, "Get".Length);
                    return tmpMethodName;
                }

                return Name;
            }
        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }

        public override bool Equals(object obj)
        {
            Method other = obj as Method;
            if (other == null && this == null)
                return true;
            if (other == null)
                return false;
            if (this == null)
                return false;
            if (other == this)
                return true;

            if (Declaration.Equals(other.Declaration))
            {
                if (Parameters.Count == 0)
                    return true;
                else
                {
                    int i = 0;
                    foreach (Parameter nextParam in Parameters)
                    {
                        if (nextParam != other.Parameters[i++])
                            return false;
                    }
                    return true;
                }
            }

            return false;
        }

        public string Declaration
        {
            get
            {
                return this.ToString();
            }
        }

        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("Name = " + Name);
            sb.Append("\n");
            sb.Append("const = " + Const);
            sb.Append("\n");
            sb.Append("Type = " + ReturnType.TypeString.Trim());
            sb.Append("\n");
            sb.Append("parameters Count = " + Parameters.Count);
            return sb.ToString();
        }
    }
}
